/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Conversion Class
 *      Provides static class for performing certain types of data conversions.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
using System;
using System.Text;
using System.Globalization;

namespace Adaptive.Foundation
{
    /// <summary>
    /// Provides static class for performing certain types of data conversions.
    /// </summary>
    public static class Conversion
    {

        /*--------------------------------------------------------------------------------
         * Public Methods / Functions
         *------------------------------------------------------------------------------*/
        #region Public Methods / Functions
        /// <summary>
        /// Converts a string to a byte array.
        /// </summary>
        /// <param name="data">
        /// The string data to be converted.
        /// </param>
        /// <returns>
        /// A byte array containing the ASCII-encoded characters.
        /// </returns>
        public static byte[] ToBytes(string data)
        {
            int count = 0;                          //Iteration counter.
            int length = 0;                         //Iteration limit.
            byte[] returnValue = null;              //Return value.

            if (data != null)
            {
                length = data.Length;
                returnValue = new byte[length];

                for (count = 0; count < length; count++)
                    returnValue[count] = (byte)Math.Abs((int)(data[count]));
            }
            return returnValue;
        }
        /// <summary>
        /// Converts a short integer to a byte array.
        /// </summary>
        /// <param name="number">
        /// The short integer value to be converted.
        /// </param>
        /// <returns>
        /// A byte array containing the bits of the number.
        /// </returns>
        public static byte[] ToBytes(short number)
        {
            byte[] returnValue = new byte[2];

            returnValue[1] = (byte)(number >> 8);
            returnValue[0] = (byte)((number << 8) >> 8);

            return returnValue;
        }
        /// <summary>
        /// Converts an integer to a byte array.
        /// </summary>
        /// <param name="number">
        /// The integer value to be converted.
        /// </param>
        /// <returns>
        /// A byte array containing the bits of the number.
        /// </returns>
        public static byte[] ToBytes(int number)
        {
            byte[] returnValue = new byte[4];

            returnValue[3] = (byte)(number >> 24);
            returnValue[2] = (byte)((number << 8) >> 24);
            returnValue[1] = (byte)((number << 16) >> 24);
            returnValue[0] = (byte)((number << 24) >> 24);

            return returnValue;
        }
        /// <summary>
        /// Converts a long integer to a byte array.
        /// </summary>
        /// <param name="number">
        /// The long integer value to be converted.
        /// </param>
        /// <returns>
        /// A byte array containing the bits of the number.
        /// </returns>
        public static byte[] ToBytes(long number)
        {
            byte[] returnValue = new byte[8];

            returnValue[7] = (byte)(number >> 56);
            returnValue[6] = (byte)((number << 8) >> 56);
            returnValue[5] = (byte)((number << 16) >> 56);
            returnValue[4] = (byte)((number << 24) >> 56);
            returnValue[3] = (byte)((number << 32) >> 56);
            returnValue[2] = (byte)((number << 40) >> 56);
            returnValue[1] = (byte)((number << 48) >> 56);
            returnValue[0] = (byte)((number << 56) >> 56);

            return returnValue;
        }
        /// <summary>
        /// Converts an ASCII-character byte array to a string.
        /// </summary>
        /// <param name="data">
        /// A byte array containing the ASCII character codes to be converted.
        /// </param>
        /// <returns>
        /// A string representing the data in the byte array.
        /// </returns>
        public static string ToString(byte[] data)
        {
            StringBuilder builder = null;
            string returnValue = null;
            int count = 0;
            int length = 0;

            if (data != null)
            {
                length = data.Length;
                builder = new StringBuilder();
                for (count = 0; count < length; count++)
                {
                    builder.Append((char)data[count]);
                }
                returnValue = builder.ToString();
            }

            builder = null;
            return returnValue;
        }
        /// <summary>
        /// Converts the specified data array to a 64-bit integer.
        /// </summary>
        /// <param name="data">
        /// A byte array containing the data to convert.
        /// </param>
        /// <returns>
        /// A 64-bit integer value as represented by the byte array.
        /// </returns>
        public static long ToInt64(byte[] data)
        {
            return BitConverter.ToInt64(data, 0);
        }
        /// <summary>
        /// Converts the specified data array to a 32-bit integer.
        /// </summary>
        /// <param name="data">
        /// A byte array containing the data to convert.
        /// </param>
        /// <returns>
        /// A 32-bit integer value as represented by the byte array.
        /// </returns>
        public static int ToInt32(byte[] data)
        {
            return BitConverter.ToInt32(data, 0);
        }
        /// <summary>
        /// Converts the specified data array to a 16-bit integer.
        /// </summary>
        /// <param name="data">
        /// A byte array containing the data to convert.
        /// </param>
        /// <returns>
        /// A 16-bit integer value as represented by the byte array.
        /// </returns>
        public static short ToInt16(byte[] data)
        {
            return BitConverter.ToInt16(data, 0);
        }
        /// <summary>
        /// Converts a byte array to an integer value.
        /// </summary>
        /// <param name="data">
        /// A byte array containing the data.
        /// </param>
        /// <returns>
        /// A long integer.  
        /// </returns>
        /// <remarks>
        /// The conversion is performed based on the length of the data.  The caller
        /// must re-cast the returned value to the desired type.
        /// </remarks>
        public static long ToInteger(byte[] data)
        {
            long returnValue = 0;               //Return value.

            if (data.Length == 2)
                returnValue = (long)BitConverter.ToInt16(data, 0);
            else if (data.Length == 4)
                returnValue = (long)BitConverter.ToInt32(data, 0);
            else
                returnValue = (long)BitConverter.ToInt64(data, 0);

            return returnValue;
        }
        /// <summary>
        /// Converts the cotents of the byte array to a hexadecimal string.
        /// </summary>
        /// <param name="data">
        /// A byte array containing the data to convert.
        /// </param>
        /// <returns>
        /// A string in hexadecimal notation where each 2 characters represents one byte of data.
        /// </returns>
        public static string ToHexadecimal(byte[] data)
        {
            StringBuilder builder = null;                   //String concatenator.
            string item = null;                             //Character translation.
            string returnValue = null;                      //Return value.
            int count = 0;                                  //Iteration counter.
            int length = 0;                                 //Iteration limit.

            if (data != null)
            {
                builder = new StringBuilder();
                length = data.Length;
                for (count = 0; count < data.Length; count++)
                {
                    item = data[count].ToString("X");
                    if (item.Length == 1)
                        builder.Append("0");
                    builder.Append(item);
                }
                returnValue = builder.ToString();
            }
            builder = null;
            item = null;
            return returnValue;
        }
        /// <summary>
        /// Converts the specified short integer into hexadecimal notation.
        /// </summary>
        /// <param name="number">The number to be converted.</param>
        /// <returns>
        /// A string in hexadecimal notation where each 2 characters represents one byte of data.
        /// </returns>
        public static string ToHexadecimal(short number)
        {
            return ToHexadecimal(ToBytes(number));
        }
        /// <summary>
        /// Converts the specified integer into hexadecimal notation.
        /// </summary>
        /// <param name="number">The number to be converted.</param>
        /// <returns>
        /// A string in hexadecimal notation where each 2 characters represents one byte of data.
        /// </returns>
        public static string ToHexadecimal(int number)
        {
            return ToHexadecimal(ToBytes(number));
        }
        /// <summary>
        /// Converts the specified long integer into hexadecimal notation.
        /// </summary>
        /// <param name="number">The number to be converted.</param>
        /// <returns>
        /// A string in hexadecimal notation where each 2 characters represents one byte of data.
        /// </returns>
        public static string ToHexadecimal(long number)
        {
            return ToHexadecimal(ToBytes(number));
        }
        /// <summary>
        /// Converts the specified string into a hexadecimal representation of the underlying ASCII
        /// character byte array.
        /// </summary>
        /// <param name="textToConvert">The text to be converted.</param>
        /// <returns>
        /// A string in hexadecimal notation where each 2 characters represents one byte of data.
        /// </returns>
        public static string ToHexadecimal(string textToConvert)
        {
            return ToHexadecimal(ToBytes(textToConvert));
        }
        /// <summary>
        /// Converts a hexadecimal string to a byte array.
        /// </summary>
        /// <param name="hexadecimalData">
        /// A string in hexadecimal notation form, which must be formatted where 2 characters
        /// represent one byte of data.
        /// </param>
        /// <returns>
        /// A byte array containing the data represented by <i>hexadecimalData</i>.
        /// </returns>
        public static byte[] HexToBytes(string hexadecimalData)
        {
            int count = 0;                          //Iteration counter.
            int length = 0;                         //Iteration limit.
            byte[] returnValue = null;              //Return value.

            if ((hexadecimalData != null) && (hexadecimalData.Length % 2 == 0))
            {
                length = hexadecimalData.Length;
                returnValue = new byte[(int)((float)length / 2)];
                for (count = 0; count < length; count += 2)
                {
                    returnValue[(int)((float)(count) / 2)] = Convert.ToByte(hexadecimalData.Substring(count, 2), 16);
                }
            }

            return returnValue;
        }
        /// <summary>
        /// Converts the specified hexadecimal data to a short integer.
        /// </summary>
        /// <param name="hexadecimalData">
        /// The hexadecimal data to be converted.
        /// </param>
        /// <returns>
        /// A short integer value.
        /// </returns>
        public static short HexToInt16(string hexadecimalData)
        {
            return ToInt16(HexToBytes(hexadecimalData));
        }
        /// <summary>
        /// Converts the specified hexadecimal data to an integer.
        /// </summary>
        /// <param name="hexadecimalData">
        /// The hexadecimal data to be converted.
        /// </param>
        /// <returns>
        /// An integer value.
        /// </returns>
        public static int HexToInt32(string hexadecimalData)
        {
            return ToInt32(HexToBytes(hexadecimalData));
        }
        /// <summary>
        /// Converts the specified hexadecimal data to a long integer.
        /// </summary>
        /// <param name="hexadecimalData">
        /// The hexadecimal data to be converted.
        /// </param>
        /// <returns>
        /// A long integer value.
        /// </returns>
        public static long HexToInt64(string hexadecimalData)
        {
            return ToInt64(HexToBytes(hexadecimalData));
        }
        /// <summary>
        /// Formats the string for usage in a SQL statement.
        /// </summary>
        /// <param name="originalData">
        /// The original text to be modified.
        /// </param>
        /// <returns>
        /// A SQL-friendly string.
        /// </returns>
        public static string ToFieldString(string originalData)
        {
            StringBuilder builder = new StringBuilder();

            if (originalData == null)
                builder.Append("NULL");
            else
            {
                builder.Append("'");
                builder.Append(System.Convert.ToString(originalData, CultureInfo.InvariantCulture).Replace("'", "''"));
                builder.Append("'");
            }
            return builder.ToString();
                            
        }
        /// <summary>
        /// Formats a numeric value for usage in a SQL Statement.
        /// </summary>
        /// <param name="originalData">
        /// The numeric value to be modified.
        /// </param>
        /// <returns>
        /// A SQL-friendly string representing the original value.
        /// </returns>
        public static string ToFieldNumber(object originalData)
        {
            string returnValue = string.Empty;

            if (originalData == null)
                returnValue = "NULL";
            else
                returnValue = System.Convert.ToString(originalData, CultureInfo.InvariantCulture).Replace(",", ".");

            return returnValue;
        }
        /// <summary>
        /// Converts the supplied Date/time structure to a SQL Statement string.
        /// </summary>
        /// <param name="originalData">
        /// The DateTime to be converted.
        /// </param>
        /// <returns>
        /// A SQL-friendly string representing the date value.
        /// </returns>
        public static string ToFieldDate(DateTime originalData)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("'");
            builder.Append(originalData.ToString("yyyyMMdd", CultureInfo.InvariantCulture));
            builder.Append("'");
            return builder.ToString();
        }
        /// <summary>
        /// Converts the supplied Date/time value to a SQL Statement string.
        /// </summary>
        /// <param name="originalData">
        /// The date/time value to be converted.
        /// </param>
        /// <returns>
        /// A SQL-friendly string representing the date value.
        /// </returns>
        public static string ToFieldDate(string originalData)
        {
            StringBuilder builder = new StringBuilder();

            if (originalData == null)
                builder.Append("NULL");
            else
            {
                DateTime value = DateTime.MinValue;

                try
                {
                    value = System.Convert.ToDateTime(originalData);
                    builder.Append("'");
                    builder.Append(value.ToString("yyyyMMdd", CultureInfo.InvariantCulture));
                    builder.Append("'");
                }
                catch
                {
                    builder.Append("NULL");
                }
            }

            return builder.ToString();
        }
        #endregion

    }
}